# -*- coding: UTF-8 -*-

import random
import os.path
import codecs
import random
from kivy import Logger
from syssettings import Dictionaries


class DictionaryWord():
    def __init__(self, text, complexity):
        self.text = text
        self.complexity = complexity


class DictionaryInfo():
    def __init__(self, file_name, description, words_count, enable_by_default):
        self.file_name = file_name
        self.description = description
        self.words_count = words_count
        self.enable_by_default = enable_by_default


class Dictionary():
    def __init__(self, dicts_to_load):
        """Loading dictionaries, witch you give it in "dicts_to_load"

        Args:
            dicts_to_load: (list of string)
        Return:
            None
        """
        dictionary_words_dict = {}
        self.dictionary_words = []
        Logger.debug('Loading %d dictionaries' % (len(dicts_to_load)))
        for name in dicts_to_load:
            path_to_dictionary = os.path.join(os.path.dirname(__file__),
                                              '..', 'data', name)
            dictionary_file = codecs.open(path_to_dictionary, encoding='utf-8',
                                          mode='r')
            for line in dictionary_file:
                tmp_list = line.split()
                if not (tmp_list[0] in dictionary_words_dict):
                    dictionary_words_dict[tmp_list[0]] = int(tmp_list[1])
                else:
                    dictionary_words_dict[tmp_list[0]] = \
                        min(dictionary_words_dict[tmp_list[0]],
                            int(tmp_list[1]))

            dictionary_file.close()

        for word in dictionary_words_dict:
            self.dictionary_words.append(
                DictionaryWord(word, dictionary_words_dict[word]))

        Logger.debug('Loaded %d words' % (len(self.dictionary_words)))

    def get_words(self, count, list_of_deny_strings):
        """ Gives list of count strings -- random words from dictionary

        Args:
            count: (int)
            list_of_deny_strings: list of strings

        Return:
            list of strings
        """
        set_of_deny_strings = set(list_of_deny_strings)
        chosen_words = []
        random.shuffle(self.dictionary_words)
        for word in self.dictionary_words:
            if word.text in set_of_deny_strings:
                continue
            chosen_words.append(word.text)
            if len(chosen_words) >= count:
                break
        Logger.debug('Selected %d words' % (len(chosen_words),))
        return chosen_words

    @staticmethod
    def parse_dictionaries_metadata():
        path_to_meta = os.path.join(os.path.dirname(__file__),
                                    '..', 'data', 'dictionaries.meta')
        dictionary_meta_file = codecs.open(path_to_meta, encoding='utf-8',
                                           mode='r')
        dicts_list = []
        for line in dictionary_meta_file:
            if (line.strip().startswith('#')):
                continue
            line = line.strip(' ')
            l = line.split(',')
            for i in range(len(l)):
                l[i] = l[i].strip(' ')
            if l[0] in Dictionaries.enabled_dictionaries:
                dicts_list.append(DictionaryInfo(l[0], l[1], int(l[2]),
                                  Dictionaries.enabled_dictionaries[l[0]]))
            elif (l[3].lower().strip() == u'true'):
                dicts_list.append(DictionaryInfo(l[0], l[1], int(l[2]), True))
            else:
                dicts_list.append(DictionaryInfo(l[0], l[1], int(l[2]), False))

        return dicts_list

    loaded_dictionary = None

    @staticmethod
    def get_dict(app_settings):
        dicts_to_load = []
        if Dictionary.loaded_dictionary is None:
            for cur_dict in Dictionary.parse_dictionaries_metadata():
                if cur_dict.enable_by_default:
                    dicts_to_load.append(cur_dict.file_name)

            Dictionary.loaded_dictionary = Dictionary(dicts_to_load)
        return Dictionary.loaded_dictionary

    @staticmethod
    def invalidate():
        Dictionary.loaded_dictionary = None
